'''
Created on Jul 21, 2012

@author: thomas_dao
'''

from app import article_async, comment_async, board_async, note_async
from entity.entity import Comment, Board, Article, Note
from google.appengine.ext import ndb
from kid import util, jinja_lib
from unique import unique
from web import base, urls
from web.base import BaseHandler
import json
import logging
from google.appengine.ext.ndb import Cursor

class CreateHandler(BaseHandler):
    @ndb.synctasklet
    @base.user_required
    def post(self):
        # Get input data
        name = self.request.params.get('name')
        
        # Create new entities
        board = Board()
        board.name = name
        board.user = util.get_current_user_key()
        board.put()
        
        # Response
        self.response.write(json.dumps(util.ndb_to_dict(board)))

class ReadHandler(BaseHandler):
    def get(self, board_id):
        board_key = ndb.Key(Board, int(board_id))
        articles = article_async.get_by_board(board_key)
        self.response.write(json.dumps(util.ndb_to_list(articles)))
        

class UpdateHandler(BaseHandler):
    @base.user_required
    def post(self):
        # Get input
        board_id = self.request.params.get('board__id')
        board_key = ndb.Key(Board, int(board_id))
        board = board_key.get()
        
        # Check for authorized user
        if board.user != util.get_current_user_key():
            pass
        else:
            article_ids = self.request.params.get('article_ids')
            article_keys = [ndb.Key(Article, int(x)) for x in article_ids]
            
            # Add or remove keys from the board list
            action = self.request.params.get('action')
            existing_articles = board.articles
            if action == "add":
                board.articles = unique(existing_articles + article_keys)
            elif action == "remove":
                board.articles = [x for x in board.articles if x not in article_keys]
            
            # Save to datastore
            board.put()
            self.response.write(json.dumps(util.ndb_to_dict(board)))
    

class DeleteHandler(BaseHandler):
    def post(self):
        board_id = self.request.params.get('board_list_id')
        board_key = ndb.Key(Board, int(board_id))
        board_key.delete()

class AddNoteToBoard(BaseHandler):
    @base.user_required
    def post(self):
        # Get input data
        note = self.request.params.get('note')
        article_id = self.request.params.get('article_id')
        article_key = ndb.Key('Article', int(article_id))
        board_id = self.request.params.get('board_id')
        board_key = ndb.Key("Board", int(board_id))
        
        new_note = Note()
        new_note.note = note
        new_note.article = article_key
        new_note.board = board_key
        new_note.user = util.get_current_user_key()
        new_note.put()
                
        # Response
        self.response.write(json.dumps(util.ndb_to_dict(new_note)))
        
class NotesInBoardHandler(BaseHandler):
    @ndb.synctasklet
    def get(self, board_id):
        board_key = ndb.Key(Board, int(board_id))
        logging.info(board_key)
        notes = yield board_async.get_notes_by_board(board_key)
        notes = yield util.ndb_to_list_async(notes, detail=["article"])
        self.response.write(json.dumps(notes))


class FollowBoardHandler(BaseHandler):
    @ndb.synctasklet
    @base.user_required
    def post(self):
        # Get input
        board_id = self.request.params.get('board_id')
        
        # Update followers
        board_key = ndb.Key(Board, int(board_id))
        user_key = util.get_current_user_key()
        board = yield board_key.get_async()
        if board.followers:
            # If user follow, append them into follower list
            # Clean up the follower list before adding new user
            if user_key in board.followers:
                board.followers = [x for x in board.followers if x != user_key]
            else:
                board.followers = board.followers + [user_key]
        else:
            board.followers = [user_key]
        
        board.followers_count = len(board.followers)
        board.put()
        self.response.write(json.dumps(util.ndb_to_dict(board)))

class CursorHandler(BaseHandler):
    @ndb.synctasklet
    def get(self):
        next_curs = self.request.get('curs')
        start_curs = None
        logging.info('next start_curs' + next_curs)
        if next_curs is not None and next_curs is not "":
            start_curs = Cursor(urlsafe=next_curs)
        
        env = jinja_lib.jinja_environment()
        template = env.get_template('board-collection.html')

        values = {}
        (boards, cur, more) = yield board_async.get_top_follow(start_cursor=start_curs)
        values['boards'] = yield util.ndb_to_list_async(boards, detail=['user'])
        
        # Fetch article belong to the boards
        board_keys = [x.key for x in boards]
        notes = yield note_async.get_by_boards(board_keys, limit=3)
        if notes:            
            notes = yield util.ndb_to_list_async(notes, detail=['article'])            
            for board in values['boards']:
                board['articles'] = [x['article'] for x in notes if x['board'] == board['id']]
                
        res = {}
        res['html'] = template.render(values)
        if cur:
            res['cursor'] = cur.urlsafe()
        
        self.response.write(json.dumps(res))
        
app = urls.app

def main():
    app.run()

if __name__ == '__main__':
    main()
